/****

    activequant - activestocks.eu

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License along
    with this program; if not, write to the Free Software Foundation, Inc.,
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

	
	contact  : contact@activestocks.eu
    homepage : http://www.activestocks.eu

 ****/
package org.activequant.broker;

import java.util.concurrent.atomic.AtomicLong;

import org.activequant.core.domainmodel.account.Order;
import org.activequant.core.domainmodel.events.OrderCancelEvent;
import org.activequant.core.domainmodel.events.OrderExecutionEvent;
import org.activequant.core.domainmodel.events.OrderUpdateEvent;
import org.activequant.core.types.TimeStamp;

/**
 * Mock broker: does nothing. Never executes any order. Updates and cancel requests are granted immediately.<br/>
 * A BrokerBase subclass. Defines the OrderTracker(OrderTrackerBase subclass) class. <br/>
 * Holds the following associated variable:
 * <ul>
 * <li>orderId(AtomicLong)</li>
 * </ul>
 * Holds the following inherited variables:
 * <ul>
 * <li>logger(IAQLogger)</li>
 * <li>orderMap(Map&lt;String,OrderTrackerBase&gt;)</li>
 * </ul>
 * <b>History:</b><br>
 *  - [01.02.2007] Created (Mike Kroutikov)<br>
 *
 *  @author Mike Kroutikov
 */
public class ExecutingMockBroker extends BrokerBase {
	/**
	 * private final AtomicLong orderId = new AtomicLong();
	 */
	private final AtomicLong orderId = new AtomicLong();
	/**
	 * Increments and returns the value of the associated orderId(AtomicLong)
	 * @return
	 */
	private long getNextOrderId() {
		return orderId.incrementAndGet();
	}
	/**
	 * An OrderTrackerBase subclass. Holds the following associated variable:
	 * <ul>
	 * <li>orderId(long)</li>
	 * </ul>
	 * Holds the following inherited variables:
	 * <ul>
	 * <li>orderEvent(Event&lt;OrderEvent&gt;)</li>
	 * <li>order(Order)</li>
	 * <li>isSubmitted(AtomicBoolean)</li>
	 * <li>isCanceled(AtomicBoolean)</li>
	 * <li>brokerAssignedId(String)</li>
	 * <li>completion(AtomicReference&lt;OrderCompletionEvent&gt;)</li>
	 * <li>openQuantity(double)</li>
	 * <li>executions(List&lt;OrderExecutionEvent&gt;)</li>
	 * </ul>
	 * @author Dimitar
	 *
	 */
	class OrderTracker extends OrderTrackerBase {
		/**
		 * private final long orderId;
		 */
		private final long orderId;
		/**
		 * Constructs an OrderTracker(extends OrderTrackerBase) using the given order(Order) and its quantity(double) to set its inherited order(Order) and openQuantity(double).<br/>
		 * Sets its associated orderId(long) with the next unique orderId (by invoking the <code>getNextOrderId()</code> method)
		 * @param order
		 */
		public OrderTracker(Order order) {
			super(order);
			orderId = getNextOrderId();
		}
		/**
		 * Returns the associated orderId(long) converted to a String immediately.<br/>
		 * In the meanwhile on a separate Thread it sleeps 25 millis , creates a fake OrderExecutionEvent and fires it.
		 */
		protected String handleSubmit() {
			Runnable r = new Runnable(){
				public void run(){
					try{Thread.sleep(25);}catch(Exception x){}
					OrderExecutionEvent oee = new OrderExecutionEvent();
					oee.setCommission(0.0);
					oee.setPrice(getOrder().getLimitPrice());
					oee.setQuantity(getOrder().getQuantity());
					oee.setEventTimeStamp(getOrder().getExecutionTargetTimeStamp());
					fireOrderEvent(oee);					
				}
			};
			Thread t = new Thread(r);
			t.start();
			
			return Long.toString(orderId);
		}
		/**
		 * Creates an OrderUpdateEvent whose timeStamp is set with the current time, an "ok" message and the given newOrder(Order) as its updated(Order). Then it
		 * invokes the inherited <code>fireOrderEvent(orderEvent)</code> with it.
		 */
		public void handleUpdate(Order newOrder) {
			super.fireOrderEvent(new OrderUpdateEvent(new TimeStamp(), "ok", newOrder)
			);
		}
		/**
		 * Creates an OrderCancelEvent whose timeStamp is set with the current time and an "at your request" message. Then it
		 * invokes the inherited <code>fireOrderEvent(orderEvent)</code> with it.
		 */
		public void handleCancel() {
			super.fireOrderEvent(new OrderCancelEvent(new TimeStamp(), "at your request")
			);
		}
	}
	/**
	 * Creates and returns an OrderTracker(extends OrderTrackerBase) using the given order(Order) and its quantity(double) to set its inherited order(Order) and openQuantity(double).<br/>
	 * Sets its associated orderId(long) with the next unique orderId (by invoking the <code>getNextOrderId()</code> method)
	 */
	@Override
	protected OrderTracker createOrderTracker(Order order) {
		return new OrderTracker(order);
	}
}
